
Imports System.ComponentModel
Imports Aricie.DNN.Caching.Analysis
Imports Aricie.DNN.UI.Attributes
Imports Aricie.ComponentModel
Imports Aricie.DNN.Caching.Client
Imports DotNetNuke.UI.WebControls
Imports Aricie.DNN.UI.WebControls.EditControls
Imports System.Xml.Serialization
Imports Aricie.DNN.ComponentModel
Imports Aricie.DNN.Services.Filtering
Imports Aricie.Services

Namespace Aricie.DNN.Caching

    Public Enum CachingKeyProcessing
        None
        Format
        Filter
    End Enum

    <Flags()> _
    Public Enum ConcurrencyMode
        NoConcurrency = 0
        Optimistic = 1
        PessimisticPut = 2
        PessimisticGet = 4
    End Enum

    <Serializable()> _
    Public Class CacheStrategy
        Implements IEnabled
        'Implements ICloneable


        Private _Enabled As Boolean = True
        'Private _Priority As System.Web.Caching.CacheItemPriority

        Private _KeyFormat As String = "{0}"
        Private _DistributionType As CacheDistributionType
        Private _SkipCatalogCheck As Boolean
        Private _ConcurrencyMode As ConcurrencyMode
        Private _CompressionThresold As Integer = 50

        Private _ClusterName As String = ""
        Private _RegionName As String
        Private _EvictionsOn As Boolean

        Private _BatchMode As BatchMode
        Private _PutTags As String
        Private _GetTags As String

        Private _TimeOutMode As TimeOutMode = Caching.TimeOutMode.MultiplicativeConstant
        Private _TimeOutConstant As Integer = 5

        Private _DisableSlidingEmulation As Boolean
        Private _DisableSynchronization As Boolean
        Private _AddGlobalDependency As Boolean = True
        Private _DisableClusterRemoval As Boolean
        Private _DisableReflectedCallBacks As Boolean
        Private _NoLocalInsertOnDistributedCachingGet As Boolean
        'Private _SurrogateSelectorTypeName As String

        Private _LogOperations As Boolean
        'Private _Statistics As CacheKeyStatistics


        Public Sub New(ByVal enabled As Boolean, ByVal keyformat As String, _
                        ByVal distributionType As CacheDistributionType, _
                        ByVal skipCatalogCheck As Boolean, _
                        ByVal concurrencyMode As ConcurrencyMode, _
                        ByVal compressionThresold As Integer, _
                        ByVal clusterName As String, _
                        ByVal regionName As String, _
                        ByVal evictionsOn As Boolean, _
                        ByVal batchMode As BatchMode, _
                        ByVal putTags As String, _
                        ByVal getTags As String, _
                        ByVal timeOutMode As TimeOutMode, _
                        ByVal timeOutConstant As Integer, _
                        ByVal disableSlidingEmulation As Boolean, _
                        ByVal disableSynchronization As Boolean, _
                        ByVal addGlobalDependency As Boolean, _
                        ByVal disableClusterRemoval As Boolean, _
                        ByVal disableReflectedCallBacks As Boolean, _
                        ByVal noLocalInsertOnDistributedCachingGet As Boolean, _
                        ByVal logOperations As Boolean)
            Me._Enabled = enabled

            Me.KeyFormat = keyformat
            Me._DistributionType = distributionType
            Me._SkipCatalogCheck = skipCatalogCheck
            Me._ConcurrencyMode = concurrencyMode
            Me._CompressionThresold = compressionThresold

            Me._ClusterName = clusterName
            Me._RegionName = regionName
            Me._EvictionsOn = evictionsOn

            Me._BatchMode = batchMode
            Me._PutTags = putTags
            Me._GetTags = getTags

            Me._TimeOutMode = timeOutMode
            Me._TimeOutConstant = timeOutConstant

            Me._DisableSlidingEmulation = disableSlidingEmulation
            Me._DisableSynchronization = disableSynchronization
            Me._AddGlobalDependency = addGlobalDependency
            Me._DisableClusterRemoval = disableClusterRemoval
            Me._DisableReflectedCallBacks = disableReflectedCallBacks
            Me._NoLocalInsertOnDistributedCachingGet = noLocalInsertOnDistributedCachingGet

            Me._LogOperations = logOperations
        End Sub

        Public Sub New()
            Me._DistributionType = CacheDistributionType.Undefined
            'Me._Statistics = New CacheKeyStatistics
            Me._RegionName = ""
            Me._EvictionsOn = True
            Me._PutTags = ""
            Me._GetTags = ""
            Me._TimeOutMode = Caching.TimeOutMode.Unchanged
            Me._TimeOutConstant = 1
        End Sub


        Public Property Enabled() As Boolean Implements IEnabled.Enabled
            Get
                Return _Enabled
            End Get
            Set(ByVal value As Boolean)
                _Enabled = value
            End Set
        End Property

        <ExtendedCategory("DistributionSettings")> _
        Public Property KeyProcessing As CachingKeyProcessing = CachingKeyProcessing.None

        <ConditionalVisible("KeyProcessing", False, True, CachingKeyProcessing.Format)> _
        <ExtendedCategory("DistributionSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property KeyFormat() As String
            Get
                Return _KeyFormat
            End Get
            Set(ByVal value As String)
                _KeyFormat = value
            End Set
        End Property

        <ConditionalVisible("KeyProcessing", False, True, CachingKeyProcessing.Filter)> _
        <ExtendedCategory("DistributionSettings")> _
        Public Property KeyFilter As ExpressionFilterInfo = New ExpressionFilterInfo()

        <ExtendedCategory("DistributionSettings")> _
        Public Property DistributionType() As CacheDistributionType
            Get
                Return _DistributionType
            End Get
            Set(ByVal value As CacheDistributionType)
                _DistributionType = value
            End Set
        End Property

        <ConditionalVisible("DistributionType", False, True, CacheDistributionType.NotDistributed)> _
        <ExtendedCategory("DistributionSettings")> _
        Public Property NotifyRemovals As Boolean


        <ExtendedCategory("DistributionSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property SkipCatalogCheck() As Boolean
            Get
                Return _SkipCatalogCheck
            End Get
            Set(ByVal value As Boolean)
                _SkipCatalogCheck = value
            End Set
        End Property

        <ExtendedCategory("DistributionSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property ConcurrencyMode() As ConcurrencyMode
            Get
                Return _ConcurrencyMode
            End Get
            Set(ByVal value As ConcurrencyMode)
                _ConcurrencyMode = value
            End Set
        End Property

        <ExtendedCategory("DistributionSettings")> _
        <Required(True)> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property CompressionThresold() As Integer
            Get
                Return _CompressionThresold
            End Get
            Set(ByVal value As Integer)
                _CompressionThresold = value
            End Set
        End Property


        <ExtendedCategory("ClusterSettings")> _
         <Editor(GetType(SelectorEditControl), GetType(EditControl))> _
        <Selector(GetType(ClusterSelectorControl), "ClusterName", "ClusterName", False, False, "Any", "", False, True)> _
        Public Property ClusterName() As String
            Get
                Return _ClusterName
            End Get
            Set(ByVal value As String)
                _ClusterName = value
            End Set
        End Property

        <ExtendedCategory("ClusterSettings")> _
        Property RegionName() As String
            Get
                Return Me._RegionName
            End Get
            Set(ByVal value As String)
                Me._RegionName = value
            End Set
        End Property

        <ExtendedCategory("ClusterSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Property EvictionsOn() As Boolean
            Get
                Return Me._EvictionsOn
            End Get
            Set(ByVal value As Boolean)
                Me._EvictionsOn = value
            End Set
        End Property




        <ExtendedCategory("BatchSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property BatchMode() As BatchMode
            Get
                Return _BatchMode
            End Get
            Set(ByVal value As BatchMode)
                _BatchMode = value
            End Set
        End Property


        Protected Function SplitTags(ByVal tags As String) As List(Of String)
            Return Common.ParseStringList(tags.ToLower)
        End Function

        <XmlIgnore()> _
        <Browsable(False)> _
        Public ReadOnly Property GetTagsList() As List(Of String)
            Get
                Return Me.SplitTags(Me._GetTags)
            End Get
        End Property

        <XmlIgnore()> _
        <Browsable(False)> _
        Public ReadOnly Property PutTagsList() As List(Of String)
            Get
                Return Me.SplitTags(Me._PutTags)
            End Get
        End Property



        <ExtendedCategory("BatchSettings")> _
        <Width(100)> _
        Property PutTags() As String
            Get
                Return Me._PutTags
            End Get
            Set(ByVal value As String)
                Me._PutTags = value
            End Set
        End Property

        <ExtendedCategory("BatchSettings")> _
        <Width(100)> _
        Public Property GetTags() As String
            Get
                Return _GetTags
            End Get
            Set(ByVal value As String)
                _GetTags = value
            End Set
        End Property






        <ExtendedCategory("TimeOutSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property TimeOutMode() As TimeOutMode
            Get
                Return _TimeOutMode
            End Get
            Set(ByVal value As TimeOutMode)
                _TimeOutMode = value
            End Set
        End Property

        <ExtendedCategory("TimeOutSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property TimeOutConstant() As Integer
            Get
                Return _TimeOutConstant
            End Get
            Set(ByVal value As Integer)
                _TimeOutConstant = value
            End Set
        End Property

        <ExtendedCategory("TimeOutSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property DisableSlidingEmulation() As Boolean
            Get
                Return _DisableSlidingEmulation
            End Get
            Set(ByVal value As Boolean)
                _DisableSlidingEmulation = value
            End Set
        End Property





        <ExtendedCategory("AdvancedSettings")> _
        Public Property DisableSynchronization() As Boolean
            Get
                Return _DisableSynchronization
            End Get
            Set(ByVal value As Boolean)
                _DisableSynchronization = value
            End Set
        End Property

        <ExtendedCategory("AdvancedSettings")> _
        Public Property AddGlobalDependency() As Boolean
            Get
                Return _AddGlobalDependency
            End Get
            Set(ByVal value As Boolean)
                _AddGlobalDependency = value
            End Set
        End Property

        <ExtendedCategory("AdvancedSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property DisableClusterRemoval() As Boolean
            Get
                Return _DisableClusterRemoval
            End Get
            Set(ByVal value As Boolean)
                _DisableClusterRemoval = value
            End Set
        End Property

        <ExtendedCategory("AdvancedSettings")> _
        Public Property DisableReflectedCallBacks() As Boolean
            Get
                Return _DisableReflectedCallBacks
            End Get
            Set(ByVal value As Boolean)
                _DisableReflectedCallBacks = value
            End Set
        End Property

        <ExtendedCategory("AdvancedSettings")> _
        <TrialLimited(Security.Trial.TrialPropertyMode.Disable)> _
        Public Property NoLocalInsertOnDistributedCachingGet() As Boolean
            Get
                Return _NoLocalInsertOnDistributedCachingGet
            End Get
            Set(ByVal value As Boolean)
                _NoLocalInsertOnDistributedCachingGet = value
            End Set
        End Property






        <ExtendedCategory("CollectedStatistics")> _
        Public Property LogOperations() As Boolean
            Get
                Return _LogOperations
            End Get
            Set(ByVal value As Boolean)
                _LogOperations = value
            End Set
        End Property




        '<Editor(GetType(PropertyEditorEditControl), GetType(EditControl))> _
        '<LabelMode(LabelMode.Top)> _
        '<Category("CollectedStatistics")> _
        'Public ReadOnly Property Statistics() As CacheKeyStatistics
        '    Get
        '        Return _Statistics
        '    End Get
        'End Property

        Public Function FormatKey(ByVal sourceKey As String) As String
            Select Case Me.KeyProcessing
                Case CachingKeyProcessing.None
                    Return sourceKey
                Case CachingKeyProcessing.Format
                    If Me._KeyFormat <> ("{0}") Then
                        Return String.Format(Me._KeyFormat, sourceKey)
                    End If
                Case CachingKeyProcessing.Filter
                    Return Me.KeyFilter.Process(sourceKey)
            End Select

            Return sourceKey
        End Function


        'Public Sub SetStatistics(ByVal value As CacheKeyStatistics)
        '    _Statistics = value
        'End Sub

        'Public Function Clone() As CacheStrategy
        '    'Return New CacheStrategy(Me._Enabled, Me._KeyFormat, Me._DistributionType, Me._SkipCatalogCheck, Me._ConcurrencyMode, Me._CompressionThresold, _
        '    '                        Me._ClusterName, Me._RegionName, Me._EvictionsOn, Me._BatchMode, Me._PutTags, Me._GetTags, _
        '    '                          Me._TimeOutMode, Me._TimeOutConstant, _
        '    '                         Me._DisableSlidingEmulation, Me._DisableSynchronization, Me._AddGlobalDependency, Me._DisableClusterRemoval, Me._DisableReflectedCallBacks, _
        '    '                         Me._NoLocalInsertOnDistributedCachingGet, Me._LogOperations)
        '    Return ReflectionHelper.CloneObject(Of CacheStrategy)(Me)
        'End Function

        'Public Function ObjectClone() As Object Implements System.ICloneable.Clone
        '    Return Clone()
        'End Function

        Public Shared Function FormatKeysInLines(keys() As String) As String
            Return String.Join(vbCrLf, keys)
        End Function

        Public Shared Function FormatKeys(ByVal keys() As String) As String
            Return String.Join(glbKeysSeparator(0), keys)
        End Function


        Public Shared glbKeysSeparator() As String = New String() {",,"}

    End Class
End Namespace